package Control;

import java.io.*;
import java.util.*;
import java.util.regex.*;

import processing.core.PApplet;
import GUI.Utils;


public class Import {

	public static void importFile(String filePath) throws FileNotFoundException{
		boolean statFile = true;
		boolean firstLine = true;
		String line;
		
		Utils.seasons = new ArrayList<Season>();
		Utils.episodes = new ArrayList<Episode>();
		Utils.characters = new ArrayList<Character>();
		Utils.catchphrases = new ArrayList<CatchPhrase>();
		Utils.firstOfSeason = new ArrayList<Episode>();
		
		String strings[] = Utils.globalProcessing.loadStrings(filePath);
		
		for(int i = 0; i < strings.length; i++){
			line = strings[i];
			//(line);
			if(line .contains("*")){
				//("Useless line - skipping");
				continue;
			}
			if(line.equals(new String("EPISODE_OVER...PRINTING_LIST_OF_CHARACTERS"))){
				firstLine = true;
				statFile = true;
				continue;
			}
			else if(line.contains("LIST_OF_CHARACTERS_OVER")){
				firstLine = true;

				continue;
			}
			if(statFile)
				processLineStats(line, firstLine);
			else;
			//processLine(line, firstLine);
			firstLine = false;
		}
		Collections.sort(Utils.characters, Character.comparator);
		
	}

	public static void importFileWords(String filePath) throws FileNotFoundException{
		boolean firstLine = true;
		String line;
		
		Episode e = null;
		
		String strings[] = 	Utils.globalProcessing.loadStrings(filePath);
		for(int i = 0; i< strings.length; i++){
			line = strings[i];
			//(line);
			if(line .contains("*")){
				//("Useless line - skipping");
				continue;
			}
			if(line.equals("END")){
				firstLine = true;
				continue;
			}
			if(firstLine){
				e = seasonEpisodeHandlerWords(line);
				firstLine = false;
				continue;
			}
			processLineWords(line, e);


		}

		
		for(Character c : Utils.characters)
			if(c.getCompleteCommonWords().size()>0){
				Collections.sort(c.getCompleteCommonWords(), CommonWord.cwp);
			}
	}

	
    public static void importDialog(String filepath) throws FileNotFoundException{
    	
    	String line = new String();
    	Character prev = null;
    	Character prev2 = null;
    	
		String strings[] = 	Utils.globalProcessing.loadStrings(filepath);
		for(int i = 0; i< strings.length; i++){
			line = strings[i];
    		if(line.contains("EPISODE")){ //change episode, reset states 
    			prev = null;
    			prev2 = null;
    			continue;
    		}
    		//System.out.println(line);
    		String nameCharacter;
    		String pieces[] = line.split("\t");
    		nameCharacter = pieces[0].trim();
    		//System.out.println(nameCharacter);
    		Character curr = Character.returnByShortName(Utils.characters, nameCharacter);
    		if(prev == null){
    			prev = curr;
    			curr = null; 
    			continue;
    		}
    		if(prev2 == null){
    			if(curr != prev){ //dialog is probable: raise affinity by 1
    				CharacterAffine ca = new CharacterAffine(curr);
    				CharacterAffine ca2 = new CharacterAffine(prev);
    				if(!curr.getCompleteAffineCharacters().contains(ca2))
    					curr.getCompleteAffineCharacters().add(ca2);
    				else{
    					ca2 = curr.getCompleteAffineCharacters().get(curr.getCompleteAffineCharacters().indexOf(ca2));
    					ca2.incrAffinity(1);
    				}
    				if(!prev.getCompleteAffineCharacters().contains(ca))
    					prev.getCompleteAffineCharacters().add(ca);
    				else{
    					ca = prev.getCompleteAffineCharacters().get(prev.getCompleteAffineCharacters().indexOf(ca));
    					ca.incrAffinity(1);
    				}
    			}
    			prev2 = prev;
    			prev = curr;
    			curr = null;
    			continue;
    		}
    		if(curr != prev){
    			CharacterAffine ca = new CharacterAffine(curr);
				CharacterAffine ca2 = new CharacterAffine(prev);
    			if(curr == prev2){ //the dialog is real: raise affinity by 3
    				if(!curr.getCompleteAffineCharacters().contains(ca2)){
    					curr.getCompleteAffineCharacters().add(ca2);
    					ca2.incrAffinity(2); //1 was set by the constructor so +2
    				}
    				else{
    					ca2 = curr.getCompleteAffineCharacters().get(curr.getCompleteAffineCharacters().indexOf(ca2));
    					ca2.incrAffinity(3);
    				}
    				if(!prev.getCompleteAffineCharacters().contains(ca)){
    					prev.getCompleteAffineCharacters().add(ca);
    					ca.incrAffinity(2);
    				}
    				else{
    					ca = prev.getCompleteAffineCharacters().get(prev.getCompleteAffineCharacters().indexOf(ca));
    					ca.incrAffinity(3);
    				}
    				prev2 = prev;
    				prev = curr;
    				curr = null;
    				continue;
    			}
    			//the dialog is probable: raise affinity by 1
    			if(!curr.getCompleteAffineCharacters().contains(ca2))
					curr.getCompleteAffineCharacters().add(ca2);
				else{
					ca2 = curr.getCompleteAffineCharacters().get(curr.getCompleteAffineCharacters().indexOf(ca2));
					ca2.incrAffinity(1);
				}
				if(!prev.getCompleteAffineCharacters().contains(ca))
					prev.getCompleteAffineCharacters().add(ca);
				else{
					ca = prev.getCompleteAffineCharacters().get(prev.getCompleteAffineCharacters().indexOf(ca));
					ca.incrAffinity(1);
				}
    			prev2 = prev;
    			prev = curr;
    			curr = null;
    		}
    		
    	}
    	for(int i = 0; i < Utils.characters.size(); i++){
    		Character c = Utils.characters.get(i);
    		Collections.sort(c.getCompleteAffineCharacters(), CharacterAffine.comparator);
    	}
    	
    }


	private static void processLine(String line, boolean firstLine){
		String name, value;
		//("1 - file of Strings: " + line);

		Scanner scanner = new Scanner(line);

		//if(firstLine){ //Line of season, episode specification
		//seasonEpisodeHandler(line);
		//}
		//Line of normal dialog

		Pattern pattern = Pattern.compile("[{}]");
		scanner.useDelimiter(pattern);
		if(scanner.hasNext()){
			name = scanner.next().trim();
			value = scanner.next().trim();

			ArrayList<String> lines;
			Character c = new Character();
			Episode ep = Utils.episodes.get(Utils.episodes.size()-1);
			Season s = Utils.seasons.get(Utils.seasons.size()-1);
			c.setShortName(name);
			if(Character.findByShortName(Utils.characters, c)){
				c = Character.returnByShortName(Utils.characters, name);
				if(ep.getNumLines().containsKey(c)){
					ep.getNumLines().put(c, ep.getNumLines().get(c)+1);
					lines = ep.getLines().get(c);
					lines.add(value);
				}
				else{
					ep.getNumLines().put(c, 1);
					lines = new ArrayList<String>();
					lines.add(value);
					ep.getLines().put(c, lines);
				}

			}
			else{
				c.setFirstAppearence(ep);
				Utils.characters.add(c);
				ep.getNewCharacters().add(c);
				s.getNewCharacters().add(c);
				ep.getNumLines().put(c, 1);
				lines = new ArrayList<String>();
				lines.add(value);
				ep.getLines().put(c, lines);
			}



			//("name: "+ name + " value: " + value);
		}



	}

	private static void processLineStats(String line, boolean firstLine){
		if(firstLine){ 	
			seasonEpisodeHandler(line);
		}
		else{

			String pieces[];
			String values[];
			String name;
			pieces = line.split("\t");
			name = pieces[0];
			values = pieces[1].split(" ");
			//System.out.print(name);
			Character character = new Character();
			character.setShortName(name);
			//System.out.print(character.getName());
			Episode ep = Utils.episodes.get(Utils.episodes.size()-1);
			//(" " + values[0]);
			if(Utils.characters.contains(character)){
				character = Character.returnByName(Utils.characters, character.getName());
				//(character.toString());
			}
			if(ep.getNumLines().containsKey(character)){
				ep.getNumLines().put(character, ep.getNumLines().get(character)+Integer.parseInt(values[0]));
			}
			else{
				ep.getNumLines().put(character, Integer.parseInt(values[0]));
			}
			for(int i = 1; i < values.length; i++){
				character.getCatchphrases().get(i-1).incrCount(Integer.parseInt(values[i]));
				ep.getNumCatchphrases().put(character.getCatchphrases().get(i-1), Integer.parseInt(values[i]));
			}
			if(!Utils.characters.contains(character)){
				ep.getNewCharacters().add(character);
				character.setFirstAppearence(ep);
				ep.getSeason().getNewCharacters().add(character);
				Utils.characters.add(character);

			}
			for(int i = 0; i < character.getCatchphrases().size(); i++){
				if(!Utils.catchphrases.contains(character.getCatchphrases().get(i)) &&
						character.getCatchphrases().get(i).getCount()>0){
					Utils.catchphrases.add(character.getCatchphrases().get(i));
					character.getCatchphrases().get(i).setFirstepisode(ep);
				}
			}
		}

	}


	private static void processLineWords(String line, Episode episode){
		String pieces[] = line.split("\t");
		Character c = null;
		c = Character.returnByShortName(Utils.characters, pieces[0]);
		ArrayList<Integer> count = new ArrayList<Integer>();
		ArrayList<String> words = new ArrayList<String>();
		for(int i = 1; i < pieces.length; i++){
			if(i % 2 == 1)
				count.add(Integer.parseInt(pieces[i]));
			else
				words.add(pieces[i].trim());
		}
		for(int i = 0; i < words.size(); i++){
			CommonWord cw = new CommonWord(words.get(i), count.get(i));
			int position = c.getCompleteCommonWords().indexOf(cw);
			if(position == -1){ //the word is not present yet
				c.addCommonWord(cw);
				//(c.getCommonWords().toString());
			}
			else{
				c.getCompleteCommonWords().get(position).increment(cw.getCount());
			}

		}


	}




	private static void seasonEpisodeHandler(String line){
		String ep_name;
		String season2, episode2;
		String set[], set2[];
		int season, episode;
		boolean firstOfSeason = false;
		//(line);
		if(!line.equals("") && line != null){
			set = line.split("\t", 2);
			set2 = set[1].split(" ",2);
			set2[0] = set2[0].concat(" ");
			season2 = set2[0].subSequence(1, 2).toString();
			episode2 = set2[0].subSequence(3,5).toString().trim();
			ep_name = set2[1];
			//ep_name = ep_name.subSequence(0, ep_name.lastIndexOf("1")-1).toString();
			//("season " + season2 + " episode " + episode2 + " ep_name " + ep_name);
			season = Integer.parseInt(season2);
			episode = Integer.parseInt(episode2);
			Season s = new Season();
			s.setNumber(season);
			if(!(Utils.seasons.contains(s))){
				Utils.seasons.add(s);
				firstOfSeason = true;
			}
			Episode e = new Episode();
			e.setName(ep_name);
			e.setNumEpisode(episode);
			if(!(Utils.episodes.contains(e))){
				Utils.episodes.add(e);
				Utils.seasons.get(season-1).getEpisodes().add(e);
				e.setSeason(Utils.seasons.get(season-1));
				if(firstOfSeason)
					Utils.firstOfSeason.add(e);
			}

		}
	}

	private static Episode seasonEpisodeHandlerWords(String line){
		String ep_name;
		String season2, episode2;
		String set[], set2[];
		int season, episode;
		//(line);
		if(!line.equals("") && line != null){
			set2 = line.split(" ",2);
			set2[0] = set2[0].concat(" ");
			season2 = set2[0].subSequence(1, 2).toString();
			episode2 = set2[0].subSequence(3,5).toString().trim();
			ep_name = set2[1];
			//ep_name = ep_name.subSequence(0, ep_name.lastIndexOf("1")-1).toString();
			//("season " + season2 + " episode " + episode2 + " ep_name " + ep_name);
			season = Integer.parseInt(season2);
			episode = Integer.parseInt(episode2);
			for(int i = 0; i < Utils.episodes.size(); i++){
				//();
				if(Utils.episodes.get(i).getSeason().getNumber() == season &&
						Utils.episodes.get(i).getNumEpisode() == episode)
					return Utils.episodes.get(i);
			}
		}
		return null;
	}



/*	public static void main(String [] args) throws FileNotFoundException{
		Import.importFile("./src/data/all_out.txt");
		//	for(int i = 0; i < Utils.episodes.size(); i++)
		//	(Utils.episodes.get(i).toString());
		Import.importFileWords("./src/data/all_words.txt");
		Import.importDialog("./src/data/all_dialogs.txt");
		for(int i = 0; i < Utils.characters.size(); i++){
			Character c = Utils.characters.get(i);
			//sdfdfefwerdgdersySystem.out.println(c.getName() + " " + c.getCommonWords().size());
			if(c.getCompleteCommonWords().size()>0){
				System.out.println(c.getName());
				for(int j = 0; j < c.getCompleteCommonWords().size() && j < 10; j++){
					System.out.println(c.getCompleteCommonWords().get(j).toString());
				}
				System.out.println("");
			}
		}


	}*/




}
